package main

import (
	"fmt"
	"github.com/go-macaron/macaron"
	"log"
	"net/http"
	"os"
	"time"
)

func main() {
	//string200()
	//string201()
	//httpMacaron()
	//macaronHandlers()
	//macaronQuery()
	//macaronRemoteAddr()
	//macaronNexts()
	//macaronCookie()
	//macaronSecureCookie()
	//macaronSuperSecureCookie()
	//macaronResp()
	//macaronStatic()
	//macaronRecoveryDev()
	//macaronRecoveryProd()
	//macaronLogger()
	macaronCustomService()
}

var logger = log.New(os.Stdout, "[App] ", 0)

type Logger interface {
	Println(...interface{})
}
type SuperLogger struct {
	*log.Logger
}

//http://localhost:4000
//http://localhost:4000/1
//http://localhost:4000/2
//http://localhost:4000/3
func macaronCustomService() {
	m := macaron.New()
	m.Map(logger)
	m.Get("/", func(l *log.Logger) {
		l.Println("这是我的全局日志器。")
	})
	m.Get("/1", func(ctx *macaron.Context) {
		ctx.Map(log.New(os.Stdout, "[MyLogger1] ", 0))
	}, func(l *log.Logger) {
		l.Println("这是我的请求日志器。")
	})
	m.Get("/2", func(ctx *macaron.Context) {
		l := log.New(os.Stdout, "[MyLogger2] ", 0)
		ctx.MapTo(l, (*Logger)(nil))
	}, func(l Logger) {
		l.Println("这是我的请求日志器。")
	})
	m.Get("/3", func(ctx *macaron.Context) {
		l := log.New(os.Stdout, "[MyLogger2] ", 0)
		ctx.MapTo(l, (*Logger)(nil))
	}, func(ctx *macaron.Context) {
		l := log.New(os.Stdout, "[MyLogger3] ", 0)
		superLogger := &SuperLogger{l}
		ctx.MapTo(superLogger, (*Logger)(nil))
	}, func(l Logger) {
		l.Println("这是我的请求日志器。")
	})
	m.Run()
}

//http://localhost:4000
func macaronService() {
	m := macaron.New()
	m.Get("/", func(l *log.Logger) {
		l.Println("这是一行日志。")
	})
	m.Run()
}

//http://localhost:4000
func macaronLogger() {
	macaron.Env = macaron.PROD
	m := macaron.Classic()
	m.Get("/", func(l *log.Logger) {
		l.Println("这是一行日志。")
	})
	m.Run()
}

//http://localhost:4000
func macaronRecoveryProd() {
	macaron.Env = macaron.PROD
	m := macaron.Classic()
	m.Get("/", func() {
		panic("this is a prod panic!")
	})
	m.Run()
}

//http://localhost:4000
func macaronRecoveryDev() {
	m := macaron.Classic()
	m.Get("/", func() {
		panic("this is a dev panic!")
	})
	m.Run()
}

//go run macaron.go
//http://localhost:4000/hello.css
//http://localhost:4000/dir
//http://localhost:4000/dir/index.html
func macaronStatic() {
	m := macaron.Classic()
	m.Run()
}

//http://localhost:4000
func macaronResp() {
	m := macaron.Classic()
	m.Get("/",
		func(ctx *macaron.Context) {
			ctx.Data["Count"] = 1
		},

		func(ctx *macaron.Context) {
			ctx.Data["Count"] = ctx.Data["Count"].(int) + 1
		},
		func(ctx *macaron.Context) {
			ctx.Data["Count"] = ctx.Data["Count"].(int) + 1
		},
		func(ctx *macaron.Context) string {
			return fmt.Sprintf("前面执行了%d个处理器", ctx.Data["Count"])
		},
		//这个处理器不会被执行
		func(ctx *macaron.Context) {
			ctx.Resp.Write([]byte("你好世界"))
		},
	)
	m.Run()
}

//http://localhost:4000/get
//http://localhost:4000/get
func macaronSuperSecureCookie() {
	m := macaron.Classic()
	m.Get("/set",
		func(ctx *macaron.Context) {
			ctx.SetSuperSecureCookie("123123", "user", "无闻")
		})
	m.Get("/get", func(ctx *macaron.Context) string {
		s, _ := ctx.GetSuperSecureCookie("123123", "user")
		return s
	})
	m.Run()
}

//http://localhost:4000/get
//http://localhost:4000/get
func macaronSecureCookie() {
	m := macaron.Classic()
	m.SetDefaultCookieSecret("macaron")
	//
	m.Get("/set",
		func(ctx *macaron.Context) {
			ctx.SetSecureCookie("user", "无闻")
		})
	m.Get("/get", func(ctx *macaron.Context) string {
		s, _ := ctx.GetSecureCookie("user")
		return s
	})
	m.Run()
}

//http://localhost:4000/set
//http://localhost:4000/get
func macaronCookie() {
	m := macaron.Classic()
	m.Get("/set",
		func(ctx *macaron.Context) {
			ctx.SetCookie("user", "无闻")
		})
	m.Get("/get", func(ctx *macaron.Context) string {
		return ctx.GetCookie("user")
	})
	m.Run()
}

//http://localhost:4000
func macaronNexts() {
	m := macaron.Classic()
	//哦你
	m.Get("/*",
		next1, next2, next3)
	m.Run()
}

func next1(ctx *macaron.Context) {
	fmt.Println("处理器1进入")
	now := time.Now()
	ctx.Next()
	fmt.Printf("耗时：%dms", time.Since(now)/time.Millisecond)
	fmt.Println("处理器1退出")
}
func next2(ctx *macaron.Context) {
	fmt.Println("处理器2进入")
	time.Sleep(time.Second * 1)
	ctx.Next()
	fmt.Println("处理器2退出")
}
func next3(ctx *macaron.Context) {
	fmt.Println("处理器3进入")
	ctx.Next()
	fmt.Println("处理器3退出")
}

//http://localhost:4000
func macaronRemoteAddr() {
	m := macaron.Classic()
	//哦你
	m.Get("/*",
		func(ctx *macaron.Context) string { return ctx.RemoteAddr() })
	m.Run()
}

//http://localhost:4000/?uid=111
func macaronQuery() {
	m := macaron.Classic()
	//哦你
	m.Get("/*",
		func(ctx *macaron.Context) string { return ctx.Query("uid") })
	m.Run()
}

//http://localhost:4000
func macaronHandlers() {
	m := macaron.Classic()
	//哦你
	m.Get("/*",
		func(ctx *macaron.Context) { ctx.Data["Num"] = 1 },
		func(ctx *macaron.Context) { ctx.Data["Num"] = ctx.Data["Num"].(int) + 1 },
		func(ctx *macaron.Context) string { return fmt.Sprintf("Num : %d", ctx.Data["Num"]) })
	m.Run()
}

//http://localhost:4000/xxx
func httpMacaron() {
	m := macaron.Classic()
	//m.Get("/", myhandler)
	//哦你
	m.Get("/*", myhandler)
	//可以使用多个handler
	//m.Get("/*", myhandler,myhandler1,myhandler2)
	log.Println("server is running")
	log.Println(http.ListenAndServe("localhost:4000", m))
}

func myhandler(ctx *macaron.Context) string {
	return "the request uri is " + ctx.Req.RequestURI
}

//http://localhost:4000
func string201() {
	m := macaron.Classic()
	m.Get("/", func() (int, string) {
		return 201, "hello world!"
	})
	m.Run()
}

//http://localhost:4000
func string200() {
	m := macaron.Classic()
	m.Get("/", func() string {
		return "hello world!"
	})
	m.Run()
}
